/**
 * Copyright (C), 2020-2021 by colley.ma File Name: RateLimitVo.java Encoding: UTF-8 Date:
 * 2021年3月25日 下午3:44:40 History:
 */
package com.swak.frame.ratelimit.config;

import com.swak.frame.dto.base.BaseOperation;
import com.swak.frame.ratelimit.annotation.RateLimit;

public class LimitOperation implements BaseOperation {
    private static final long serialVersionUID = -8663031715419784133L;

    private String resource;

    private String name;

    private int qps;

    private int capacity;

    // 是否开启限流
    private boolean enable;

    private boolean remote = false;

    private int instances;

    private boolean dynamic;

    private RateLimit rateLimit;

    private boolean first = true;

    public LimitOperation() {}

    public static LimitOperation newLimitOperation(String resource, RateLimit rateLimit,
        String desc) {
        LimitOperation.Builder builder = new LimitOperation.Builder();
        builder.rateLimit(rateLimit).qps(rateLimit.qps()).resource(resource)
            .enable(rateLimit.qps() > 0).name(desc).first(true);
        return builder.build();
    }

    public LimitOperation(int qps, RateLimit rateLimit) {
        this.qps = qps;
        this.enable = (qps > 0);
    }

    public int getCapacity() {
        return Math.max(qps, capacity);
    }

    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }

    public int getQps() {
        return qps;
    }

    public void setQps(int qps) {
        this.qps = qps;
    }

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }

    public boolean isRemote() {
        return remote;
    }

    public void setRemote(boolean remote) {
        this.remote = remote;
    }

    public String getResource() {
        return resource;
    }

    public void setResource(String resource) {
        this.resource = resource;
    }

    public RateLimit getRateLimit() {
        return rateLimit;
    }

    public void setRateLimit(RateLimit rateLimit) {
        this.rateLimit = rateLimit;
    }

    public void reset() {
        this.qps = rateLimit.qps();
        this.dynamic = false;
        this.first = false;
    }

    public int getInstances() {
        return instances;
    }

    public void setInstances(int instances) {
        this.instances = instances;
    }

    public boolean isDynamic() {
        return dynamic;
    }

    public void setDynamic(boolean dynamic) {
        this.dynamic = dynamic;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isFirst() {
        return first;
    }

    public void setFirst(boolean first) {
        this.first = first;
    }

    public static class Builder {
        private String resource;
        private String name;
        private int qps;
        private int capacity;
        private boolean enable;
        private boolean remote;
        private int instances;
        private boolean dynamic;
        private RateLimit rateLimit;
        private boolean first;

        public Builder resource(String resource) {
            this.resource = resource;
            return this;
        }

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder qps(int qps) {
            this.qps = qps;
            return this;
        }

        public Builder capacity(int capacity) {
            this.capacity = capacity;
            return this;
        }

        public Builder enable(boolean enable) {
            this.enable = enable;
            return this;
        }

        public Builder remote(boolean remote) {
            this.remote = remote;
            return this;
        }

        public Builder instances(int instances) {
            this.instances = instances;
            return this;
        }

        public Builder dynamic(boolean dynamic) {
            this.dynamic = dynamic;
            return this;
        }

        public Builder rateLimit(RateLimit rateLimit) {
            this.rateLimit = rateLimit;
            return this;
        }

        public Builder first(boolean first) {
            this.first = first;
            return this;
        }

        public LimitOperation build() {
            return new LimitOperation(this);
        }
    }

    private LimitOperation(Builder builder) {
        this.resource = builder.resource;
        this.name = builder.name;
        this.qps = builder.qps;
        this.capacity = builder.capacity;
        this.enable = builder.enable;
        this.remote = builder.remote;
        this.instances = builder.instances;
        this.dynamic = builder.dynamic;
        this.rateLimit = builder.rateLimit;
        this.first = builder.first;
    }
}
